from . import varint
from .SerialTypeCodesFormat import SerialTypeCodesFormat
from .Sqlite3Common import DEFAULT_PAGE_SIZE


class Sqlite3CellReader:
    def __init__(self, page_size=DEFAULT_PAGE_SIZE):
        self.page_size = page_size

    def parse(self, page, address):
        try:
            cell_size, cell_size_size = varint.decode_bytes(page[address:])
            _, rowid_size = varint.decode_bytes(page[address+cell_size_size:])
            cell_header_size = cell_size_size + rowid_size
            if address + cell_size + cell_header_size > self.page_size:
                return None

            types, header_size = self.read_header(page, address + cell_header_size)

            # 目前已知最多为firefox, moz_places有15个字段
            if header_size == 0 or not types or cell_size < header_size or len(types) > 15 or len(types) < 2:
                return None
            record = self.read_data(types, page[address+cell_header_size +
                                                header_size:address+cell_header_size+cell_size])
            return record
        except Exception as err:
            # record处理有错误，则丢弃掉整个record
            # print(err) #
            return None

    def read_header(self, page, header_addr):
        header_size, read_size = varint.decode_bytes(page[header_addr:])

        if header_addr + header_size > self.page_size or read_size != 1:
            return None, 0

        types = []
        while header_size > read_size:
            type_i, type_i_size = varint.decode_bytes(page[header_addr+read_size:])
            types.append(type_i)
            read_size += type_i_size

        return types, header_size

    def read_data(self, types, data):
        offset = 0
        record = []
        for type_i in types:
            value, value_size = SerialTypeCodesFormat().convert(type_i, data, offset)
            offset += value_size
            record.append(value)
        return record
